﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Djs.Common.Components;

namespace Djs.Common
{
    public partial class TestForm : Form
    {
        public TestForm()
        {
            InitializeComponent();
            InitInteractive();
        }
        private void InitInteractive()
        {
            // this._GInteractiveControl.PaintToBuffer += new PaintEventHandler(_GInteractiveControl_PaintToBuffer);

            this._ActiveList = new List<IInteractiveItem>();
            this._ActiveList.Add(new TestActiveItem() { ActiveBounds = new Rectangle(20, 210, 60, 30), Color = Color.CornflowerBlue, Angle = 90f });
            this._ActiveList.Add(new TestActiveItem() { ActiveBounds = new Rectangle(60, 250, 60, 30), Color = Color.LightGreen, Angle = 90f });
            this._ActiveList.Add(new TestActiveItem() { ActiveBounds = new Rectangle(40, 290, 60, 30), Color = Color.PaleGoldenrod, Angle = 90f });
            this._ActiveList.Add(new TestActiveItem() { ActiveBounds = new Rectangle(80, 330, 60, 30), Color = Color.PaleVioletRed, Angle = 90f });
            
            this._ActiveList.Add(new TestActiveItem() { ActiveBounds = new Rectangle(140, 255, 60, 30), Color = Color.PaleVioletRed, Angle = 90f});
            this._ActiveList.Add(new TestActiveItem() { ActiveBounds = new Rectangle(180, 330, 60, 30), Color = Color.CornflowerBlue, Angle = 90f });
            this._ActiveList.Add(new TestActiveItem() { ActiveBounds = new Rectangle(160, 295, 60, 30), Color = Color.LightGreen, Angle = 90f });
            this._ActiveList.Add(new TestActiveItem() { ActiveBounds = new Rectangle(200, 210, 60, 30), Color = Color.PaleGoldenrod, Angle = 90f });

            this._TimeAxis = new GTimeAxis();
            DateTime now = DateTime.Now;
            DateTime begin = (new DateTime(now.Year, now.Month, now.Day)).AddDays(1 - ((int)now.DayOfWeek));
            DateTime end = begin.AddDays(2);
            this._TimeAxis.TimeRangeInternal = new TimeRange(begin, end);
            this._TimeAxis.BoundsInternal = new Rectangle(10, 170, 500, 40);
            this._TimeAxis.BackColor = Color.LightCyan;
            this._TimeAxis.BackColor3DEffect = 0.2f;
            this._ActiveList.Add(this._TimeAxis);

            this._Splitter = new GSplitter() { Orientation = System.Windows.Forms.Orientation.Horizontal, Bounds = new Rectangle(5, 20, 200, 5), ActiveOverhead = 3, Location = 60 };
            this._Splitter.LocationChanging += new EventHandler(_Splitter_LocationChanging);
            this._ActiveList.Add(this._Splitter);

            this._TimeAxisPos();

            this._SizeAxisH = new GSizeAxis();
            this._SizeAxisH.ValueMax = new SizeRange(-100m, 1000m);
            this._SizeAxisH.ValueSilent = new SizeRange(0m, 200m);
            this._SizeAxisH.BoundsInternal = new Rectangle(10, 300, 500, 25);
            this._SizeAxisH.Orientation = AxisOrientation.Top;
            this._SizeAxisH.BackColor = Color.FromArgb(248, 252, 255);
            this._SizeAxisH.BackColor3DEffect = 0.2f;
            this._ActiveList.Add(this._SizeAxisH);

            this._SizeAxisV = new GSizeAxis();
            this._SizeAxisV.ValueMax = new SizeRange(-100m, 1000m);
            this._SizeAxisV.ValueSilent = new SizeRange(0m, 200m);
            this._SizeAxisV.BoundsInternal = new Rectangle(5, 5, 25, 500);
            this._SizeAxisV.Orientation = AxisOrientation.LeftDown;
            this._SizeAxisV.BackColor = Color.FromArgb(248, 252, 255);
            this._SizeAxisV.BackColor3DEffect = 0.1f;
            this._ActiveList.Add(this._SizeAxisV);

            this._SizeAxisV.SynchronizeMode = AxisSynchronizeMode.Scale;
            this._SizeAxisH.SynchronizedSlaveAxisList.Add(this._SizeAxisV);
            this._SizeAxisH.SynchronizeMode = AxisSynchronizeMode.Scale;
            this._SizeAxisV.SynchronizedSlaveAxisList.Add(this._SizeAxisH);
            
            this._SizeAxisPos();


            this._ScrollBarH = new GScrollBar() { ActiveBounds = new Rectangle(2, 200, 400, 12), ValueTotal = new SizeRange(0, 1000), Value = new SizeRange(400, 600) };
            this._ActiveList.Add(this._ScrollBarH);
            this._ScrollBarV = new GScrollBar() { ActiveBounds = new Rectangle(400, 2, 12, 400), ValueTotal = new SizeRange(0, 1000), Value = new SizeRange(800, 900) };
            this._ActiveList.Add(this._ScrollBarV);
            this._ScrollBarPos();


            this.MovableArea1 = new GEditableArea() { Bounds = new Rectangle(400, 95, 90, 25), BackColor = Color.CadetBlue };
            this._ActiveList.Add(this.MovableArea1);
            this.MovableArea2 = new GEditableArea() { Bounds = new Rectangle(500, 95, 100, 25), BackColor = Color.LightYellow };
            this._ActiveList.Add(this.MovableArea2);
            this.MovableArea3 = new GEditableArea() { Bounds = new Rectangle(400, 125, 90, 30), BackColor = Color.LimeGreen };
            this._ActiveList.Add(this.MovableArea3);
            this.MovableArea4 = new GEditableArea() { Bounds = new Rectangle(500, 125, 100, 30) };
            this._ActiveList.Add(this.MovableArea4);

            this._GInteractiveControl.Items = this._ActiveList;

            this._GInteractiveControl.ResizeBeforeDraw += new EventHandler(_GInteractiveControl_ResizeBeforeDraw);
        }
        void _Splitter_LocationChanging(object sender, EventArgs e)
        {
            this._TimeAxisPos();
        }
        void _GInteractiveControl_ResizeBeforeDraw(object sender, EventArgs e)
        {
            this._TimeAxisPos();
            this._SizeAxisPos();
            this._ScrollBarPos();
        }
        void _TimeAxisPos()
        {
            Rectangle gic = this._GInteractiveControl.ClientRectangle;
            int splitY = this._Splitter.Location;
            Rectangle tax = new Rectangle(gic.Left + 60, 10, gic.Width - 80, splitY - 12);
            this._TimeAxis.Bounds = tax;           // set value to Bounds ensure RepaintAll items
            this._Splitter.Bounds = new Rectangle(tax.Left, tax.Bottom + 25, tax.Width, 5);
        }
        void _SizeAxisPos()
        {
            Rectangle gic = this._GInteractiveControl.ClientRectangle;
            Rectangle tax = new Rectangle(gic.Left + 60, gic.Bottom - 45, gic.Width - 80, 25);
            this._SizeAxisH.Bounds = tax;           // set value to Bounds ensure RepaintAll items
            tax = new Rectangle(gic.Left + 5, 10, 55, gic.Height - 30);
            this._SizeAxisV.Bounds = tax;           // set value to Bounds ensure RepaintAll items
        }
        private void _ScrollBarPos()
        {
            Rectangle gic = this._GInteractiveControl.ClientRectangle;
            this._ScrollBarH.ActiveBounds = new Rectangle(gic.X, gic.Bottom - 15, gic.Width - 15, 15);
            this._ScrollBarV.ActiveBounds = new Rectangle(gic.Right - 15, gic.Y, 15, gic.Height - 15);
        }
        protected List<IInteractiveItem> _ActiveList;
        protected GTimeAxis _TimeAxis;
        protected GSizeAxis _SizeAxisV;
        protected GSizeAxis _SizeAxisH;
        protected GScrollBar _ScrollBarH;
        protected GScrollBar _ScrollBarV;
        protected GEditableArea MovableArea1;
        protected GEditableArea MovableArea2;
        protected GEditableArea MovableArea3;
        protected GEditableArea MovableArea4;
        protected Djs.Common.Components.GSplitter _Splitter;
        private void button1_Click(object sender, EventArgs e)
        {
            this._SizeAxisH.Value = new SizeRange(100, 500);
            this._SizeAxisV.Value = new SizeRange(100, 500);
            this._GInteractiveControl.Draw();
        }
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            bool enabled = this._AxisEnabledCheck.Checked;
            this._TimeAxis.Enabled = enabled;
            this._SizeAxisH.Enabled = enabled;
            this._SizeAxisV.Enabled = enabled;
        }
    }
    public class TestActiveItem : InteractiveItem, IInteractiveItem
    {
        protected Rectangle? BoundsOrigin { get; set; }
        public Color Color { get; set; }
        public float Angle { get; set; }
        public Point? MouseCenter { get; set; }
        protected override GInteractiveStyles Style { get { return GInteractiveStyles.AllInteractivity; } }
        #region Interactive
        protected override void StateChanged(GInteractiveChangeStateArgs e)
        {
            e.ToolTip = "";
            string toolText = null;
            if (e.MouseRelativePoint.HasValue && this.Color == Color.LightGreen)
                toolText = "MousePosition = " + e.MouseRelativePoint.Value.Add(this.ActiveBounds.Location).ToString();
            switch (e.ChangeState)
            {
                case GInteractiveChangeState.MouseEnter:
                    this.Angle = 270f;
                    this.RepaintToLayers = GInteractiveDrawLayer.Standard;
                    e.ToolTip = toolText;
                    break;
                case GInteractiveChangeState.MouseOver:
                    this.MouseCenter = e.MouseRelativePoint;
                    this.RepaintToLayers = GInteractiveDrawLayer.Standard;
                    e.ToolTip = toolText;
                    break;
                case GInteractiveChangeState.LeftDragBegin:
                    this.MouseCenter = null;
                    this.Angle = 0f;
                    this.BoundsOrigin = this.ActiveBounds;
                    this.RepaintAllItems = true;
                    this.RepaintToLayers = GInteractiveDrawLayer.Interactive;
                    e.RequiredCursorType = SysCursorType.SizeAll;
                    e.ToolTip = toolText;
                    break;
                case GInteractiveChangeState.LeftDragMove:
                    this.ActiveBounds = e.DragToBounds.Value;
                    this.RepaintToLayers = GInteractiveDrawLayer.Interactive;
                    e.ToolTip = toolText;
                    break;
                case GInteractiveChangeState.LeftDragEnd:
                    this.Angle = 270f;
                    this.BoundsOrigin = null;
                    this.RepaintAllItems = true;
                    e.RequiredCursorType = SysCursorType.Default;
                    e.ToolTip = toolText;
                    // this.RepaintToLayers = GInteractiveDrawLayer.Standard;
                    break;
                case GInteractiveChangeState.RightClick:
                    this.Color = Color.Gray;
                    this.RepaintToLayers = GInteractiveDrawLayer.Standard;
                    break;
                case GInteractiveChangeState.MouseLeave:
                    this.MouseCenter = null;
                    this.Angle = 90f;
                    this.MouseCenter = null;
                    this.RepaintAllItems = true;
                    // this.RepaintToLayers = GInteractiveDrawLayer.Standard;
                    break;
            }
        }
        #endregion
        #region Draw
        protected override void Draw(GInteractiveDrawArgs e)
        {
            if (this.ActiveBounds.X >= 160 && this.ActiveBounds.Right <= 760)
                this._DrawButton(e);
            else
                this._DrawNative(e);
        }
        private void _DrawButton(GInteractiveDrawArgs e)
        {
            if (this.IsDrawAsGhost(e))
                GPainter.DrawButtonBase(e.Graphics, this.ActiveBounds, this.Color, GInteractiveState.None, Orientation.Horizontal, null, 64);
            else
                GPainter.DrawButtonBase(e.Graphics, this.ActiveBounds, this.Color, this.CurrentState, Orientation.Horizontal, this.MouseCenter, null);
        }
        private void _DrawNative(GInteractiveDrawArgs e)
        {
            if (this.MouseCenter.HasValue)
            {
                Rectangle r = this.ActiveBounds;
                Point[] pts = new Point[]
                    {
                        new Point(r.Left, r.Top), 
                        new Point(r.Right, r.Top),
                        new Point(r.Right, r.Bottom), 
                        new Point(r.Left, r.Bottom), 
                        new Point(r.Left, r.Top)
                    };
                using (System.Drawing.Drawing2D.PathGradientBrush p = new System.Drawing.Drawing2D.PathGradientBrush(pts))
                {
                    p.CenterPoint = new PointF(r.X + this.MouseCenter.Value.X, r.Y + this.MouseCenter.Value.Y);
                    p.CenterColor = Color.White;
                    p.SurroundColors = new Color[] { this.Color, this.Color, this.Color, this.Color, this.Color };
                    e.Graphics.FillRectangle(p, this.ActiveBounds);
                }
            }
            else if (this.IsDragged)
            {
                if (e.DrawLayer == GInteractiveDrawLayer.Standard)
                {   // Kreslím objekt, který je přemísťován, ale do spodní vrstvy = jeho původní umístění:
                    using (System.Drawing.SolidBrush b = new SolidBrush(Color.FromArgb(96, this.Color)))
                    {
                        e.Graphics.FillRectangle(b, this.BoundsOrigin.Value);
                    }
                }
                else
                {   // Kreslím objekt, který je přemísťován, do horní = interaktivní vrstvy = jeho nové umístění:
                    using (System.Drawing.Drawing2D.LinearGradientBrush b = new System.Drawing.Drawing2D.LinearGradientBrush(this.ActiveBounds, this.Color, Color.White, this.Angle))
                    {
                        e.Graphics.FillRectangle(b, this.ActiveBounds);
                    }
                }
            }
            else
            {   // Normální objekt:
                using (System.Drawing.Drawing2D.LinearGradientBrush b = new System.Drawing.Drawing2D.LinearGradientBrush(this.ActiveBounds, this.Color, Color.White, this.Angle))
                {
                    e.Graphics.FillRectangle(b, this.ActiveBounds);
                }
            }
        }
        #endregion
    }
}
